package com.examiner.service.impl;


import com.examiner.bean.CommonPerson;
import com.examiner.bean.Department;
import com.examiner.bean.Job;
import com.examiner.bean.test.TestDB;
import com.examiner.bean.test.TestItem;
import com.examiner.bean.test.TestType;
import com.examiner.bean.vo.TestDBVO;
import com.examiner.bean.vo.TestTypeVO;
import com.examiner.dao.*;
import com.examiner.page.QueryInfo;
import com.examiner.service.TestDBService;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.transaction.Transactional;
import java.util.ArrayList;
import java.util.List;

@Service
public class TestDBServiceImpl implements TestDBService {
    @Resource
    private TestDBDao testDBDao;

    @Resource
    private TestTypeDao testTypeDao;

    @Resource
    private TestItemDao testItemDao;

    @Resource
    private CommonPersonDao commonPersonDao;

    @Resource
    private DepartmentDao departmentDao;

    @Resource
    private JobDao jobDao;

    /**
     * 添加考评库内容
     * @param testDBVO
     */
    @Override
    @Transactional
    public void save(TestDBVO testDBVO) throws Exception{
        saveMethod("save",testDBVO);
    }

    /**
     * 删除
     * @param testId
     * @throws Exception
     */
    @Override
    @Transactional
    public void deleteTestDB(Integer testId) throws Exception {
        try{
            List<TestType> testTypes = testTypeDao.findBySid(testId);
            for (TestType testType : testTypes) {
                testItemDao.deleteBySid(testType.getTestTypeId());
            }
            testTypeDao.deleteBySid(testId);
            testDBDao.deleteById(testId);
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    /**
     * 修改考评库内容
     * @param testDBVO
     * @throws Exception
     */
    @Override
    @Transactional
    public void updateTestDB(TestDBVO testDBVO) throws Exception {
        saveMethod("update",testDBVO);
    }

    /**
     * 改变考评库状态
     * @param testDBId
     * @param testState
     */
    @Override
    public void changeTestState(Integer testDBId, Boolean testState) {

    }

    @Override
    public List<TestDB> getTestDBList(QueryInfo queryInfo) {
        return testDBDao.findByQuery((queryInfo.getPageNum()-1)* queryInfo.getPageSize(),queryInfo.getPageSize(),queryInfo.getQuery());
    }

    @Override
    public List<TestDB> getTestDBList(QueryInfo queryInfo, Integer id) {
        List<CommonPerson> userList = new ArrayList<>();
        List<CommonPerson> superiors = getSuperior(userList, id);
        List<String> userStrs = new ArrayList<>();
        for (CommonPerson commonPerson : superiors) {
            userStrs.add(commonPerson.getUserName());
        }
        return testDBDao.getListByUser((queryInfo.getPageNum() - 1)* queryInfo.getPageSize(),queryInfo.getPageSize(),queryInfo.getQuery(),userStrs);
    }

    /**
     * 获取本人及所有上级
     * @param id
     * @return
     */
    private List<CommonPerson> getSuperior(List<CommonPerson> userList,Integer id){
        CommonPerson user = commonPersonDao.getOne(id);
        if (user.getId() != 1 ){
            userList.add(user);
            if (user.getStype().equals("部门")){
                Department one = departmentDao.getOne(user.getSId());
                findSJob(userList,jobDao.getOne(one.getSId()));
            }else if(user.getStype().equals("职位")) {
                //  获取 当前用户 的 同级用户
                List<CommonPerson> commonPersonList = commonPersonDao.findBySIdAndStype(user.getSId(), user.getStype());
                if (commonPersonList.size() > 0){
                    userList.addAll(commonPersonList);
                }
                // 获取职位上级
                findSJob(userList,jobDao.getOne(user.getSId()));
            }
        }
        return userList;
    }
    // 查询上级职位
    private void findSJob(List<CommonPerson> userList, Job job){
        //  获取 上级职位 的 同级用户
        List<CommonPerson> commonPersonList = commonPersonDao.findBySIdAndStype(job.getId(), job.getType());
        if (commonPersonList.size() > 0){
            userList.addAll(commonPersonList);
        }
        // 获取职位上级
        Job one = jobDao.getOne(job.getSid());
        if (!job.getUserName().equals("部门和职位管理")){
            findSJob(userList,one);
        }
    }

    @Transactional
    @Override
    public int getTestDBByUserTotal(String query, Integer id) {
        List<CommonPerson> userList = new ArrayList<>();
        List<CommonPerson> superiors = getSuperior(userList, id);
        List<String> userStrs = new ArrayList<>();
        for (CommonPerson commonPerson : superiors) {
            userStrs.add(commonPerson.getUserName());
        }
        return testDBDao.getListTotalByUser(query,userStrs);
    }


    @Transactional
    @Override
    public int getTestDBTotal(String query) {
        return testDBDao.getTotal(query);
    }

    /**
     * 根据id获取考评库内容
     * @param testId
     * @return
     */
    @Transactional
    @Override
    public TestDBVO getTestDbById(Integer testId) {
        TestDBVO testDBVO = new TestDBVO();
        TestTypeVO testTypeVO;
        List<TestTypeVO> testTypeVOS = new ArrayList<>();
        TestDB testDB = testDBDao.getOne(testId);
        testDBVO.setTestId(testDB.getTestId());
        testDBVO.setTestTitle(testDB.getTestTitle());
        testDBVO.setTestTotalGrade(testDB.getTestTotalGrade());
        testDBVO.setTestCreate(testDB.getTestCreate());
        testDBVO.setTestState(testDB.getTestState());
        List<TestType> testTypes = testTypeDao.findBySid(testId);
        for (TestType testType : testTypes) {
            testTypeVO = new TestTypeVO();
            testTypeVO.setTestTypeId(testType.getTestTypeId());
            testTypeVO.setTestTypeName(testType.getTestTypeName());
            testTypeVO.setSid(testType.getSid());
            List<TestItem> testItems = testItemDao.findBySid(testType.getTestTypeId());
            testTypeVO.setTestItems(testItems);
            testTypeVOS.add(testTypeVO);
        }
        testDBVO.setTestTypes(testTypeVOS);
        return testDBVO;
    }



    public void saveMethod(String method,TestDBVO testDBVO){
        TestDB testDB = new TestDB();
        TestType testType;
        TestItem testItem;
        int totalGrade = 0;
        if (method.equals("update")){
            TestDBVO testDbById = getTestDbById(testDBVO.getTestId());
            for (TestTypeVO type : testDbById.getTestTypes()) {
                boolean flag = false;
                for (TestTypeVO typeVO : testDBVO.getTestTypes()) {
                    if (type.getTestTypeId().equals(typeVO.getTestTypeId())){
                        flag = true;
                        for (TestItem item1 : type.getTestItems()) {
                            boolean itemFlag = false;
                            for (TestItem item2 : typeVO.getTestItems()) {
                                if (item1.getTestItemId().equals(item2.getTestItemId())) {
                                    itemFlag = true;
                                    break;
                                }
                            }
                            if(!itemFlag){
                                testItemDao.deleteById(item1.getTestItemId());
                            }
                        }
                    }
                }
                if (!flag){
                    testTypeDao.deleteById(type.getTestTypeId());
                }
            }
        }
        // 保存 testDB
            if (method.equals("update")) testDB.setTestId(testDBVO.getTestId());
            testDB.setTestTitle(testDBVO.getTestTitle());
            testDB.setTestState(true);
            testDB.setTestTotalGrade(testDBVO.getTestTotalGrade());
            testDB.setTestCreate(testDBVO.getTestCreate());
            TestDB reTestDB = testDBDao.save(testDB);
            // 保存 testType
            for (TestTypeVO type : testDBVO.getTestTypes()) {
                testType = new TestType();
                if (method.equals("update") && type.getTestTypeId()!= null) testType.setTestTypeId(type.getTestTypeId());
                testType.setTestTypeName(type.getTestTypeName());
                testType.setSid(reTestDB.getTestId());
                TestType reTestType = testTypeDao.save(testType);
                // 保存 testItem
                for (TestItem item : type.getTestItems()) {
                    testItem = new TestItem();
                    if (method.equals("update") && item.getTestItemId() != null) testItem.setTestItemId(item.getTestItemId());
                    testItem.setTestItemName(item.getTestItemName());
                    testItem.setTestItemGrade(item.getTestItemGrade());
                    testItem.setSid(reTestType.getTestTypeId());
                    totalGrade += testItem.getTestItemGrade();
                    testItemDao.save(testItem);
                }
            }
            reTestDB.setTestTotalGrade(totalGrade);
            testDBDao.save(reTestDB);
    }
}
